package com.zhuhjay.common.web.config;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.zhuhjay.common.base.constant.TimeConstant;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ZhuHJay
 * @date 2023/2/24 23:20
 */
@Configuration
public class JacksonConfig {

    /** Jackson 全局 序列化/反序列化 规则配置 **/
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TimeConstant.DATE_TIME_FORMAT);
            // LocalDateTime 序列化和反序列化
            builder.serializerByType(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
                @Override
                public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    if (value != null) {
                        // 将其解析成 yyyy-MM-dd HH:mm:ss 格式
                        String res = value.atZone(ZoneId.systemDefault()).format(formatter);
                        gen.writeString(res);
                    }
                }
            }).deserializerByType(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
                @Override
                public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
                        throws IOException {
                    // 反序列化成 LocalDateTime
                    String value = p.getValueAsString();
                    if (StrUtil.isNotBlank(value)) {
                        return LocalDateTime.parse(value, formatter);
                    }
                    return null;
                }
            });
            // HttpServletRequest 序列化
            builder.serializerByType(HttpServletRequest.class, new JsonSerializer<HttpServletRequest>() {
                @Override
                public void serialize(HttpServletRequest value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    gen.writeString("@HttpServletRequest@");
                }
            });
            // HttpServletResponse 序列化
            builder.serializerByType(HttpServletResponse.class, new JsonSerializer<HttpServletResponse>() {
                @Override
                public void serialize(HttpServletResponse value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    gen.writeString("@HttpServletResponse@");
                }
            });
            // MultipartFile 序列化
            builder.serializerByType(MultipartFile.class, new JsonSerializer<MultipartFile>() {
                @Override
                public void serialize(MultipartFile value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    if (value != null) {
                        Map<String, String> map = new HashMap<>(4);
                        map.put("fileName", value.getOriginalFilename());
                        map.put("contentType", value.getContentType());
                        map.put("size", String.valueOf(value.getSize()));
                        gen.writeObject(map);
                    }
                }
            });

        };
    }

}
